<script setup lang="js">
import { onMounted, ref, computed, defineEmits } from 'vue'
import { useI18n } from 'vue-i18n'
import { useMapAddress } from '../../stores/mapAdress.js'
import mapIcon from '../../pages/dataAnalyze/images/mapIcon.png'
import Pie from './pie.vue'

const { t } = useI18n()
const store = useMapAddress()
const emits = defineEmits(['send-message'])

const props = defineProps({
  category: {
    type: String,
    required: true
  }
})

let map = null
let geocoder = null

const center = computed(() => {
  return store.getCenter(props.category) || { lng: 112.9388, lat: 28.2282 }
})

const icon = new T.Icon({
  iconUrl: mapIcon,
  iconSize: new T.Point(40, 45)
})

const inputAddress = ref('')
const mapPointsAddress = computed(() => store.getList(props.category))
const arrayMarks = []
const mapPoints = ref([])

const sidebarRef = ref(null)
const showSidebar = ref(false)

function searchResult(result) {
  if (result.getStatus() === 0) {
    store.setCenterStore(result.getLocationPoint(), props.category)
    map.panTo(result.getLocationPoint(), 15)
    let marker = new T.Marker(result.getLocationPoint())
    map.addOverLay(marker)
  } else {
    alert(result.getMsg())
  }
}

function search() {
  const address = inputAddress.value
  geocoder.getPoint(address, searchResult)
}

const convertAndShowPoints = (addressList) => {
  const total = addressList.length;
  let count = 0;

  for (const address of addressList) {
    geocoder.getPoint(address.residence, (result) => {
      if (result.getStatus() === 0) {
        const markerAddress = result.getLocationPoint();
        const content = {
          ID: address.elderlyId,
          name: address.elderlyName,
          gender: address.gender
        };
        mapPoints.value.push(markerAddress);
        const marker = new T.Marker(markerAddress, { icon: icon });

        addHoverHandler(content, marker);
        arrayMarks.push(marker);
      }

      count++;
      if (count === total) {
        if (arrayMarks.length > 0) {
          if (window.markerClusterer) {
            window.markerClusterer.clearMarkers();
          }

          window.markerClusterer = new T.MarkerClusterer(map, {
            markers: arrayMarks,
            maxZoom: 15,
            gridSize: 80,
            minimumClusterSize: 2,
          });
        }
      }
    });
  }
}

function addHoverHandler(content, marker) {
  marker.addEventListener('click', () => {
    sendMessage(content.ID, true)
  })
  marker.addEventListener('mouseover', (e) => {
    openInfo(content, e)
  })
  marker.addEventListener('mouseout', () => {
    map.closeInfoWindow()
  })
}

const sendMessage = (userId, flag) => {
  emits('send-message', userId, flag)
}

function openInfo(content, e) {
  let point = e.lnglat
  const html = `
    <div style="font-size:14px;">
      <strong>${content.name}</strong><br/>
      <p><em>ID: ${content.ID}</em></p>
      <p>${content.gender}</p>
    </div>
  `
  map.openInfoWindow(new T.InfoWindow(html, { offset: new T.Point(0, -30) }), point)
}

const initMap = () => {
  const T = window.T
  map = new T.Map('tian-map', {
    projection: 'EPSG:900913',
    minZoom: 12,
    maxZoom: 20,
    zoom: 15,
  })
  geocoder = new T.Geocoder()
  map.centerAndZoom(new T.LngLat(center.value.lng, center.value.lat), 15)
  map.isScrollWheelZoom(true)
}

onMounted(async () => {
  await store.fetchDataElderly()
  initMap()
  convertAndShowPoints(mapPointsAddress.value)

  document.addEventListener('mousemove', (e) => {
    if (e.clientX <= 10) {
      showSidebar.value = true
    }
  })

  document.addEventListener('click', (e) => {
    const sidebarEl = sidebarRef.value
    if (sidebarEl && !sidebarEl.contains(e.target)) {
      showSidebar.value = false
    }
  })
})
</script>

<template>
  <div id="tian-map">
    <!-- 搜索框 -->
    <div class="search-box">
      <input type="text" :placeholder="$t('searchAddress')" v-model="inputAddress" @keydown.enter="search" />
      <input type="button" :value="$t('search')" @click="search" />
    </div>

    <!-- 侧边栏图表 -->
    <div class="slide-panel" ref="sidebarRef" :class="{ visible: showSidebar }">
      <div class="panel-header">
        <span>{{ $t('chartDisplay') }}</span>
      </div>
      <Pie/>
    </div>
  </div>
</template>

<style scoped lang="less">
#tian-map {
  position: relative;
  width: 100vw;
  height: 100vh;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.search-box {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(240, 240, 240, 0.75);
  padding: 10px 20px;
  border-radius: 10px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
  display: flex;
  gap: 12px;
  z-index: 1000;
  backdrop-filter: blur(8px);
}

input[type="text"] {
  padding: 8px 14px;
  width: 320px;
  font-size: 15px;
  border: 1px solid #ccc;
  border-radius: 8px;
  outline: none;
  background-color: #fafafa;
}

input[type="text"]:focus {
  border-color: #999999;
  background-color: #fff;
}

input[type="button"] {
  padding: 8px 18px;
  font-size: 15px;
  background-color: #d0d4d8;
  border: none;
  border-radius: 8px;
  cursor: pointer;
}

input[type="button"]:hover {
  background-color: #b0b6bc;
}

/* 侧边栏样式 */
.slide-panel {
  position: absolute;
  top: 0;
  left: -500px; /* 初始隐藏位置 */
  width: 480px;
  height: 100vh;
  background-color: rgba(255, 255, 255, 0.75);
  box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1);
  z-index: 999;
  transition: left 0.3s ease;
  backdrop-filter: blur(6px);
  padding: 10px;
}

.slide-panel.visible {
  left: 0;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: bold;
  margin-bottom: 10px;
}
</style>
